<template>
  <a-layout style="min-height: 100vh; background: #f5f7fa;">
    <!-- 顶部导航 -->
    <nav-bar />

    <a-layout-content style="padding: 30px 50px; max-width: 1400px; margin: 0 auto; width: 100%;">
      <a-button type="link" @click="$router.back()" style="margin-bottom: 16px; padding-left: 0;">
        <template #icon><arrow-left-outlined /></template>
        {{ $t('detail.back') }}
      </a-button>

      <a-spin :spinning="loading" :tip="$t('detail.loading')">
        <a-row :gutter="[16, 16]" v-if="protein">
          <!-- 基本信息卡片 -->
          <a-col :xs="24" :lg="12">
            <a-card :title="$t('detail.basicInfo')" style="border-radius: 8px; border: 1px solid #e4e7ed;">
              <a-descriptions :column="1" bordered size="small">
                <a-descriptions-item :label="$t('detail.fields.id')">
                  {{ protein.id }}
                </a-descriptions-item>
                <a-descriptions-item :label="$t('detail.fields.species')">
                  <a-tooltip :title="protein.species" placement="topLeft">
                    <a-tag style="max-width: 400px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block;">
                      {{ protein.species }}
                    </a-tag>
                  </a-tooltip>
                </a-descriptions-item>
                <a-descriptions-item :label="$t('detail.fields.assembly')">
                  <a-tooltip :title="protein.assembly" placement="topLeft">
                    <span style="max-width: 400px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block;">
                      {{ protein.assembly }}
                    </span>
                  </a-tooltip>
                </a-descriptions-item>
                <a-descriptions-item :label="$t('detail.fields.accession')">
                  <a-typography-text copyable>{{ protein.accession }}</a-typography-text>
                </a-descriptions-item>
                <a-descriptions-item :label="$t('detail.fields.neighbor')">
                  <a-tooltip :title="protein.the_neighbor_of" placement="topLeft">
                    <span style="max-width: 400px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block;">
                      {{ protein.the_neighbor_of || '-' }}
                    </span>
                  </a-tooltip>
                </a-descriptions-item>
                <a-descriptions-item :label="$t('detail.fields.type')">
                  <a-tag>{{ protein.type }}</a-tag>
                </a-descriptions-item>
                <a-descriptions-item :label="$t('detail.fields.structure')">
                  <a-tag :color="protein.has_pdb ? 'success' : 'default'">
                    {{ protein.has_pdb ? $t('detail.fields.available') : $t('detail.fields.unavailable') }}
                  </a-tag>
                </a-descriptions-item>
                <a-descriptions-item :label="$t('detail.fields.createdAt')">
                  {{ formatTime(protein.created_at) }}
                </a-descriptions-item>
              </a-descriptions>
            </a-card>
          </a-col>

          <!-- 3D结构查看器 -->
          <a-col :xs="24" :lg="12">
            <a-card 
              :title="$t('detail.structure3D')" 
              style="border-radius: 8px; border: 1px solid #e4e7ed;"
            >
              <template #extra v-if="protein.has_pdb">
                <a-button 
                  type="primary" 
                  size="small"
                  :loading="downloading"
                  @click="handleDownloadPDB"
                  :disabled="downloading"
                >
                  <template #icon><download-outlined /></template>
                  {{ $t('detail.downloadPDB') }}
                </a-button>
              </template>
              <div v-if="protein.has_pdb">
                <!-- 下载进度条 -->
                <div v-if="downloading && downloadProgress > 0" style="margin-bottom: 12px;">
                  <a-progress 
                    :percent="downloadProgress" 
                    :status="downloadProgress === 100 ? 'success' : 'active'"
                    :show-info="true"
                  />
                  <div style="font-size: 12px; color: #909399; margin-top: 4px; text-align: center;">
                    {{ $t('detail.downloading', { progress: downloadProgress, size: formatFileSize(downloadedSize), total: formatFileSize(totalSize) }) }}
                  </div>
                </div>
                
                <div id="viewer-container" style="width: 100%; height: 400px; position: relative; background: #263238; border-radius: 6px;"></div>
                <div style="margin-top: 12px;">
                  <a-space wrap>
                    <a-button @click="setStyle('cartoon')" size="small">{{ $t('detail.viewer.cartoon') }}</a-button>
                    <a-button @click="setStyle('stick')" size="small">{{ $t('detail.viewer.stick') }}</a-button>
                    <a-button @click="setStyle('sphere')" size="small">{{ $t('detail.viewer.sphere') }}</a-button>
                    <a-button @click="setStyle('line')" size="small">{{ $t('detail.viewer.line') }}</a-button>
                    <a-button @click="resetView" size="small" type="primary">{{ $t('detail.viewer.reset') }}</a-button>
                  </a-space>
                </div>
                <a-alert 
                  :message="$t('detail.viewer.info')" 
                  type="info" 
                  show-icon 
                  style="margin-top: 12px;"
                />
              </div>
              <a-empty v-else :description="$t('detail.noStructure')" />
            </a-card>
          </a-col>

          <!-- 序列信息 -->
          <a-col :span="24">
            <a-card :title="$t('detail.sequenceInfo')" style="border-radius: 8px; border: 1px solid #e4e7ed;">
              <a-tabs>
                <a-tab-pane key="protein" :tab="$t('detail.proteinSequence')">
                  <div style="background: #fafafa; padding: 16px; border-radius: 6px; font-family: 'Courier New', monospace; word-break: break-all; line-height: 1.8; color: #2c3e50; border: 1px solid #e4e7ed;">
                    {{ formatSequence(protein.protein_sequence) }}
                  </div>
                  <a-typography-text type="secondary" style="display: block; margin-top: 8px;">
                    {{ $t('detail.sequenceLength.protein', { length: protein.protein_sequence?.length || 0 }) }}
                  </a-typography-text>
                </a-tab-pane>
                <a-tab-pane key="cds" :tab="$t('detail.cdsSequence')">
                  <div style="background: #fafafa; padding: 16px; border-radius: 6px; font-family: 'Courier New', monospace; word-break: break-all; line-height: 1.8; color: #2c3e50; border: 1px solid #e4e7ed;">
                    {{ formatSequence(protein.cds) }}
                  </div>
                  <a-typography-text type="secondary" style="display: block; margin-top: 8px;">
                    {{ $t('detail.sequenceLength.cds', { length: protein.cds?.length || 0 }) }}
                  </a-typography-text>
                </a-tab-pane>
              </a-tabs>
            </a-card>
          </a-col>
        </a-row>
      </a-spin>
    </a-layout-content>
  </a-layout>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
import { ArrowLeftOutlined, DownloadOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { useI18n } from 'vue-i18n'
import axios from 'axios'
import config from '../config/env'
import NavBar from '../components/NavBar.vue'

const route = useRoute()
const { t } = useI18n()
const selectedKeys = ref([])
const loading = ref(false)
const protein = ref(null)
const downloading = ref(false)
const downloadProgress = ref(0)
const downloadedSize = ref(0)
const totalSize = ref(0)
let viewer = null

const fetchProteinDetail = async () => {
  loading.value = true
  try {
    const proteinId = route.params.id
    const response = await axios.get(`${config.API_BASE_URL}/protein/${proteinId}`)
    protein.value = response.data

    if (response.data.has_pdb) {
      setTimeout(() => load3DStructure(proteinId), 100)
    }
  } catch (error) {
    message.error(t('detail.loadError') + ': ' + (error.response?.data?.detail || error.message))
  } finally {
    loading.value = false
  }
}

const load3DStructure = async (proteinId) => {
  try {
    if (!window.$3Dmol) {
      const script = document.createElement('script')
      script.src = 'https://3Dmol.csb.pitt.edu/build/3Dmol-min.js'
      script.onload = () => loadPDB(proteinId)
      document.head.appendChild(script)
    } else {
      loadPDB(proteinId)
    }
  } catch (error) {
    console.error('加载3D结构失败:', error)
    message.error('加载3D结构失败')
  }
}

const loadPDB = async (proteinId) => {
  try {
    const response = await axios.get(`${config.API_BASE_URL}/pdb/${proteinId}`)
    const pdbData = response.data.pdb_content

    const element = document.getElementById('viewer-container')
    if (!element) return

    viewer = window.$3Dmol.createViewer(element, {
      backgroundColor: '#263238'
    })

    viewer.addModel(pdbData, 'pdb')
    viewer.setStyle({}, { cartoon: { color: 'spectrum' } })
    viewer.zoomTo()
    viewer.render()
  } catch (error) {
    console.error('加载PDB文件失败:', error)
    message.error('加载PDB文件失败')
  }
}

const setStyle = (style) => {
  if (!viewer) return

  viewer.setStyle({}, {})
  switch (style) {
    case 'cartoon':
      viewer.setStyle({}, { cartoon: { color: 'spectrum' } })
      break
    case 'stick':
      viewer.setStyle({}, { stick: { colorscheme: 'Jmol' } })
      break
    case 'sphere':
      viewer.setStyle({}, { sphere: { colorscheme: 'Jmol' } })
      break
    case 'line':
      viewer.setStyle({}, { line: { colorscheme: 'Jmol' } })
      break
  }
  viewer.render()
}

const resetView = () => {
  if (!viewer) return
  viewer.zoomTo()
  viewer.render()
}

const formatTime = (timeStr) => {
  if (!timeStr) return '-'
  const date = new Date(timeStr)
  return date.toLocaleString('zh-CN')
}

const formatSequence = (sequence) => {
  if (!sequence) return ''
  return sequence.match(/.{1,60}/g)?.join('\n') || sequence
}

const formatFileSize = (bytes) => {
  if (!bytes || bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return (Math.round(bytes / Math.pow(k, i) * 100) / 100).toFixed(2) + ' ' + sizes[i]
}

const handleDownloadPDB = async () => {
  if (!protein.value || !protein.value.has_pdb) {
    message.warning(t('detail.noPDBFile'))
    return
  }

  downloading.value = true
  downloadProgress.value = 0
  downloadedSize.value = 0
  totalSize.value = 0

  try {
    const proteinId = route.params.id
    const response = await axios.get(`${config.API_BASE_URL}/pdb/${proteinId}/download`, {
      responseType: 'blob',
      onDownloadProgress: (progressEvent) => {
        if (progressEvent.total) {
          totalSize.value = progressEvent.total
          downloadedSize.value = progressEvent.loaded
          downloadProgress.value = Math.round((progressEvent.loaded / progressEvent.total) * 100)
        } else {
          // 如果没有total，至少显示已下载的大小
          downloadedSize.value = progressEvent.loaded
          downloadProgress.value = Math.min(Math.round((progressEvent.loaded / (progressEvent.loaded + 100000)) * 100), 99)
        }
      }
    })

    // 创建下载链接
    const blob = new Blob([response.data], { type: 'application/octet-stream' })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    
    // 从响应头获取文件名
    const contentDisposition = response.headers['content-disposition']
    let filename = `${protein.value.accession || `protein_${proteinId}`}.pdb`
    if (contentDisposition) {
      const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/i)
      if (filenameMatch && filenameMatch[1]) {
        filename = decodeURIComponent(filenameMatch[1].replace(/['"]/g, ''))
      }
    }
    
    link.download = filename
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    
    downloadProgress.value = 100
    message.success(t('detail.downloadSuccess'))
  } catch (error) {
    console.error('下载PDB文件失败:', error)
    message.error(t('detail.downloadError') + ': ' + (error.response?.data?.detail || error.message))
  } finally {
    // 延迟重置进度条，让用户看到100%
    setTimeout(() => {
      downloading.value = false
      downloadProgress.value = 0
      downloadedSize.value = 0
      totalSize.value = 0
    }, 1000)
  }
}

onMounted(() => {
  fetchProteinDetail()
})

onUnmounted(() => {
  if (viewer) {
    viewer = null
  }
})
</script>

<style scoped>
:deep(.ant-descriptions-item-label) {
  font-weight: 600;
  background: #fafafa;
  color: #2c3e50;
}

:deep(.ant-menu-item) {
  font-weight: 500;
  color: #606266;
}

:deep(.ant-menu-item-selected) {
  color: #409eff !important;
  font-weight: 600;
}

:deep(.ant-card-head-title) {
  color: #2c3e50;
  font-weight: 600;
}

:deep(.ant-btn-primary) {
  background: #409eff;
  border-color: #409eff;
}
</style>